// declare VILViewer UI controller
var VILViewerUI = (new function() {
	var viewer = null;
	this.initialized = false;
	var logger = new Logger("VILViewer");
	var autoFit = true;
	var panel = null;
	var thumbs = null;
	var main_img_div = null;
	var main_img = null;
	var main_img_desc = null;
	var main_img_info = null;
	var main_img_container = null;
	var main_img_control = null;
	var main_img_status = null;
	var main_img_buf = new Image();
	var img_max_size = {
		w : 0,
		h : 0
	};
	var scrollBoxObject = null;
	var show_control = false;
	var infobar = false;
	var currentLoc = "";
	var preloadImages = new Array;
	var preloadSize = 3;
	this.init = function(obj) {
		setup(obj);
		preloadSize = vilPlusPrefs.getIntPref("preload.size", 3);
		for (var i = -preloadSize; i <= preloadSize; i++) {
			preloadImages[i + preloadSize] = new Image();
		}
		this.initialized = (viewer) ? true : false;
		logger.debug("initialized:" + this.initialized);
	}
	function setup(obj) {
		viewer = obj;
		// use getAnonymousElementByAttribute to access XBL binding nodes
		panel = document.getAnonymousElementByAttribute(viewer, "anonid",
				"VIL_thumbs_panel");
		thumbs = panel.childNodes;
		main_img_container = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_container");
		main_img = document.getAnonymousElementByAttribute(viewer, "anonid",
				"main_img");
		main_img_status = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_status");
		main_img_div = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_div");
		main_img_desc = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_desc");
		main_img_info = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_info");
		main_img_control = document.getAnonymousElementByAttribute(viewer,
				"anonid", "main_img_control");
		viewer.autoFit = true;
		scrollBoxObject = panel.boxObject
				.QueryInterface(Components.interfaces.nsIScrollBoxObject);
		$(main_img_buf).load(setMainImageSize);
	}
	this.clearImages = function() {
		$(main_img_div).removeClass("img-shadow");
		$(thumbs).remove();
		$(main_img).removeAttr("height").removeAttr("width").attr("src",
				"chrome://vilplus/skin/Throbber_inverse.gif")
		$(main_img_status).val("loading.....").show();
		$(main_img_control).hide();
	}
	this.addImages = function(urlInfoObjs) {
		if (!urlInfoObjs || !urlInfoObjs.constructor
				|| urlInfoObjs.constructor.name != "Array") {
			return;
		}
		var len = Math.ceil(urlInfoObjs.length / 10);
		for (var i = 0; i < len; i++) {
			window.setTimeout(function(urlInfoObjs, i) {
				var start = 10 * i;
				var end = start + 10;
				var urls = urlInfoObjs.slice(start, end);
				logger.debug("adding " + start + " to " + end + ", real:"
						+ urls.length);
				$(main_img_status).val("loading " + (start + urls.length)
						+ " / " + urlInfoObjs.length);
				for (var j = 0; j < urls.length; j++) {
					VILViewerUI.addImage(urls[j]);
				}
				if (thumbs.length == urlInfoObjs.length) {
					VILViewerUI.goFirst();
				}
			}, 1000 * (i + 1), urlInfoObjs, i);
		}
	}
	this.addImage = function(urlInfoObj) {
		if (!urlInfoObj || "object" != typeof urlInfoObj) {
			return;
		}
		var thumb = document.createElement("VILThumbnail");
		panel.appendChild(thumb);
		thumbs = panel.childNodes;
		thumb.thumb = urlInfoObj.thumb;
		thumb.desc = urlInfoObj.desc;
		thumb.src = urlInfoObj.src;
		thumb.link = urlInfoObj.link;
		thumb.index = thumbs.length - 1;
	}
	function preloadImage(idx) {
		for (var i = -preloadSize; i <= preloadSize; i++) {
			var j = idx + i;
			if (j < 0) {
				continue;
			} else if (j >= thumbs.length) {
				break;
			}
			var thumb = thumbs[j];
			if (thumb && preloadImages[i + preloadSize]) {
				preloadImages[i + preloadSize].src = thumb.src;
				logger.debug("preload[" + (i + preloadSize) + "] image src: "
						+ thumb.src);
			}
		}
	}
	function setMainImageSize() {
		if (!main_img_buf.src) {
			// return if src = "";
			return;
		}
		var thumb = thumbs[viewer.index];
		$(main_img_desc).val(thumb.desc);
		$(main_img_info).val((viewer.index + 1) + "/" + thumbs.length);
		$(main_img).hide().end();
		main_img.src = thumb.src;
		var w = main_img_buf.width;
		var h = main_img_buf.height;
		if (viewer.autoFit) {
			var res = VILViewerUI.fitSizeBy(w, h);
			w = res.width;
			h = res.height;
		}
		var tl = centering(w, h);
		logger.debug("setting img size to w: " + w + ", h:" + h + ", left:"
				+ tl.left + ", top:" + tl.top);
		$(main_img_div).addClass("img-shadow").parent().attr(tl);
		$(main_img_status).hide();
		$(main_img).attr({
			"height" : h,
			"width" : w
		}).end();
		$(main_img).fadeIn("fast");
		preloadImage(viewer.index);
		thumb.focus();
		if (scrollBoxObject) {
			scrollBoxObject.ensureElementIsVisible(thumb);
		}
		toggleControl(infobar);
	}
	this.fitSizeBy = function(width, height, maxWidth, maxHeight) {
		if ('undefined' == typeof maxWidth) {
			maxWidth = img_max_size.w;
		}
		if ('undefined' == typeof maxHeight) {
			maxHeight = img_max_size.h;
		}
		var mratio = (maxWidth / maxHeight);
		var ratio = (width / height);
		logger
				.debug("fit w:" + width + ", h:" + height + ", r:" + ratio
						+ " to mw:" + maxWidth + ", mh:" + maxHeight + ", mr:"
						+ mratio);
		var wo = width >= maxWidth;
		var ho = height >= maxHeight;
		var ro = ratio >= mratio;
		// reduced by boolean algebra
		if (ho || wo) {
			if (!ho || ro) {
				// fit by width
				height = Math.round(maxWidth / width * height);
				width = maxWidth;
			} else {
				// fit by height
				if (height > maxHeight) {
					width = Math.round(maxHeight / height * width);
					height = maxHeight;
				}
			}
		}
		logger.debug("resized to: w:" + width + ", h:" + height);
		return {
			"width" : width,
			"height" : height
		};
	}
	function centering(w, h) {
		var t = ((img_max_size.h - h) / 2);
		var l = ((img_max_size.w - w) / 2);
		return {
			"top" : (t < 0 ? 0 : t),
			"left" : (l < 0 ? 0 : l)
		};
	}
	function fadeOutCallback() {
		img_max_size.w = main_img_container.boxObject.width - 24;
		img_max_size.h = main_img_container.boxObject.height - 24;
		// reset img size to 0, this will reset container size
		$(main_img).removeAttr("height").removeAttr("width").attr("src",
				"chrome://vilplus/skin/Throbber_inverse.gif").end();
		var tl = centering(20, 20);
		$(main_img_div).removeClass("img-shadow").parent().attr(tl);
		$(main_img_status).val("loading.....").show();
		$(main_img).show();
		// reset imgbuf size
		$(main_img_buf).attr("src", "").removeAttr("height")
				.removeAttr("width").attr("src", thumbs[viewer.index].src);
	}
	function doImageSelected(v) {
		logger.debug("going to : " + v + ", " + thumbs[v]);
		if (!thumbs[v]) {
			return;
		}
		viewer.index = v;
		var thumb = thumbs[v];
		logger.debug("going to : " + thumb.src);
		$(main_img).fadeOut("fast", fadeOutCallback);
	}
	this.goIndex = function(i) {
		var v = parseInt(i, 10);
		doImageSelected(v);
	}
	this.goFirst = function() {
		if (viewer.collapsed)
			return;
		this.goIndex(0);
	}
	this.goPrev = function() {
		if (viewer.collapsed)
			return;
		if (viewer.index > 0) {
			this.goIndex(viewer.index - 1);
		}
	}
	this.goNext = function() {
		if (viewer.collapsed)
			return;
		if (viewer.index < thumbs.length - 1) {
			this.goIndex(viewer.index + 1);
		}
	}
	this.goLast = function() {
		if (viewer.collapsed)
			return;
		this.goIndex(thumbs.length - 1);
	}
	this.toggleAutoFit = function() {
		if (viewer.collapsed)
			return;
		viewer.autoFit = (!viewer.autoFit);
		logger.debug("switched to :" + viewer.autoFit);
		this.goIndex(viewer.index);
		return true;
	}
	this.toggleThumbsPanel = function() {
		if (viewer.collapsed)
			return;
		panel.collapsed = (panel.collapsed) ? false : true;
		if (!panel.collapsed) {
			scrollBoxObject.ensureElementIsVisible(thumbs[viewer.index]);
		}
		this.goIndex(viewer.index);
		return true;
	}
	this.toggleViewer = function() {
		var splitter = _gel("VILViewerSplitter");
		var content = _gel("content");
		content.collapsed = !content.collapsed;
		splitter.collapsed = !splitter.collapsed;
		viewer.collapsed = !viewer.collapsed;
		if (!viewer.collapsed) {
			// opening
			this.refreshImages();
		}
		return true;
	}
	this.refreshImages = function() {
		// 24px for shadow
		img_max_size.w = main_img_container.boxObject.width - 24;
		img_max_size.h = main_img_container.boxObject.height - 24;
		logger.debug("size of img_container w: " + img_max_size.w + " h:"
				+ img_max_size.h);
		var content = _gel("content");
		var docLoc = content.selectedBrowser.contentDocument.location;
		if (docLoc != currentLoc) {
			this.clearImages();
			var urls = vilplus.getFilterResult(docLoc);
			logger.debug("got filter result for url:" + docLoc + ":"
					+ (urls ? urls.toSource() : "[]"));
			if (urls && urls.length > 0) {
				var tl = centering(20, 20);
				$(main_img_div).removeClass("img-shadow").parent().attr(tl);
				$(main_img_status).val("loading.....");
				$(main_img).show();
				this.addImages(urls);
				currentLoc = docLoc;
			} else {
				var tl = centering(20, 20);
				$(main_img_div).parent().attr(tl);
				if (!urls) {
					$(main_img_status).val("filter not found for current URL");
					$(main_img).attr("src",
							"chrome://vilplus/skin/bullet-warning.png").show();
				} else if (urls.length == 0) {
					$(main_img_status).val("no images found in filter result");
					$(main_img).attr("src",
							"chrome://vilplus/skin/bullet-question.png").show();
				}
			}
		}
		if (thumbs.length > 0 && viewer.index == 0) {
			// opened && at first
			this.goFirst();
		}
	}
	function toggleControl(flag) {
		logger.debug("toggle control: " + flag);
		if (thumbs.length == 0) {
			// no images
			return;
		}
		var st = window.getComputedStyle(main_img_control, '');
		var mh = parseInt(st.maxHeight, 10);
		var tlc = centering(img_max_size.w - 24, mh);
		if (flag) {
			$(main_img_control).css({
				"width" : img_max_size.w - 24,
				"top" : img_max_size.h - mh + 24,
				"left" : tlc.left
			}).fadeIn("fast");
		} else {
			$(main_img_control).fadeOut("fast");
		}
		// centering
		var tl = centering(main_img.width, main_img.height);
		$(main_img_div).parent().attr(tl);
	}
	this.toggleInfo = function() {
		infobar = (!infobar);
		toggleControl(infobar);
	}
});
// register resize event for
window.addEventListener("resize", function(e) {
	defaultLogger.debug("resize event...");
	var VILViewer = _gel("VILViewer");
	if (!VILViewer.collapsed) {
		VILViewer.goIndex(VILViewer.index);
	}
}, true);
